package derk;

import java.io.IOException;
import java.util.Arrays;

import derk.sam.DKCloudID;
import derk.sam.IDCardData;
import derk.sam.SerialRXTX;
import derk.sam.SerialRXTX.onReceiveDataListener;
import derk.ui.DerkUI;
import derk.utils.StringTool;
import derk.utils.UtilTool;

public class Client {
	public static final String UART_NAME_STRING = "COM34";        /*串口号，请根据实际串口号修改*/
	
	public static final byte SAM_V_FRAME_START_CODE = (byte)0xBB; /* 扩展通讯协议帧头定义 */
	public static final byte SAM_V_INIT_COM = (byte)0x32;   	  /* 解析服务器开始请求解析命令 */
	public static final byte SAM_V_APDU_COM = (byte)0x33;   	  /* 解析服务器APDU命令 */
	public static final byte SAM_V_FINISH_COM = (byte)0x34;   	  /* 解析服务器解析完成命令 */
	public static final byte SAM_V_ERROR_COM = (byte)0x35;   	  /* 解析服务器解析错误命令 */
	public static final byte SAM_V_GET_AES_KEY_COM = (byte)0x36;  /* 获取明文解谜密钥 */
	public static final String DERVER_REG_CMD = "AA19A3cadc85c7899bf43d936e934d48eeec783130303030303130";
	
	static DKCloudID dkCloudID = null;
    public static final int NUMBER_OF_REPARSING = 5;              /*解析失败时，重新解析的次数*/
    static int err_cnt = 0;
    static int schedule = 1;
    static byte[] initData;
    static SerialRXTX serialManager;
	
	public static int number = 1;
	
    public static void main(String []args) {
    	//uid初始化
    	new DerkUI().setVisible(true);
    	
        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                serialManager = new SerialRXTX();

                serialManager.listAvailablePorts();
                try {
                	serialManager.connect(UART_NAME_STRING);
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                serialManager.setOnReceiveDataListener(new onReceiveDataListener() {
                    @Override
                    public void OnReceiverData(String portNumberString, byte[] data) {
                    	if ( (data != null) && (data[0] == SAM_V_FRAME_START_CODE) ) {
                        	//数据长度校验
                        	if ( data.length < 6 ) {
                                DerkUI.logViewln( "数据长度错误！" );
                    			if ( dkCloudID != null ) {
                    				dkCloudID.Close();
                            	}
                        		return;
                        	}
                    		
                    		//和校验
                    		byte bcc_sum = 0;
                    		for ( int i=0; i<data.length - 1; i++ ) {
                    			bcc_sum ^= data[i];
                    		}
                    		if ( bcc_sum != data[data.length - 1] ) {
                                System.out.println("和校验失败");
                                DerkUI.logViewln( "和校验失败！" );
                    			if ( dkCloudID != null ) {
                    				dkCloudID.Close();
                            	}
                    			return;
                    		}
                    		
                    		switch ( data[3] ) {
	                    		case SAM_V_INIT_COM:      //接收到开始解析请求
	                    			DerkUI.showIDMsg(null);
                                    System.out.println("开始解析");
                                    schedule = 1;
                                    if ( dkCloudID != null ) {
                                        dkCloudID.Close();
                                    }
                                    dkCloudID = new DKCloudID();
                                    initData = Arrays.copyOfRange( data, 4, data.length - 1 );
                                    continue_to_parse(initData);
	                    			break;
	                    			
                                case SAM_V_APDU_COM:
                                    byte[] apduBytes = Arrays.copyOfRange( data, 4, data.length - 1 );
                                    continue_to_parse(apduBytes);
                                    break;
                                    
	                    		case SAM_V_ERROR_COM:
                                    final int errorCode = ((data[4] & 0xff) << 8) | (data[5] & 0xff);
                                    DerkUI.logViewln( "解析出错：" + errorCode );

                                    if (err_cnt++ < NUMBER_OF_REPARSING) {
                                    	DerkUI.logViewln( "正在重新解析.." );
                                        try {
											serialManager.sendMessage(StringTool.hexStringToBytes("AA0118"));
										} catch (IOException e) {
											// TODO Auto-generated catch block
											e.printStackTrace();
										}
                                    }
                                    else {
                                        err_cnt = 0;
                                    }
	                    			break;
	                    			
                    			default:
                    				break;
                    		}
                    	}
                    	else if (StringTool.byteHexToSting(data).equals("aa01ea")) {
                            if ( dkCloudID != null ) {
                                dkCloudID.Close();
                            }
                            System.out.println("卡片已经拿开");
                        }
                    }
                });
            }
        }).start();
    }
    
    public static void continue_to_parse(byte[] apduBytes) {
    	DerkUI.logViewln(String.format("正在解析%%%d", (int)((++schedule) * 100 / 5.0)));

        byte[] cloudReturnByte = dkCloudID.dkCloudTcpDataExchange(apduBytes);

        if ( (cloudReturnByte == null) || (cloudReturnByte.length < 2)
                || ((cloudReturnByte[0] != 0x03) && (cloudReturnByte[0] != 0x04)) ) {
            
            if ( cloudReturnByte == null ) {
            	DerkUI.logViewln("服务器返回数据为空");
            }
            else if (cloudReturnByte[0] == 0x05) {
            	DerkUI.logViewln("解析失败, 请重新读卡");
            }
            else if (cloudReturnByte[0] == 0x06) {
            	DerkUI.logViewln("该设备未授权, 请联系www.derkiot.com获取授权");
            }
            else if (cloudReturnByte[0] == 0x07) {
            	DerkUI.logViewln("该设备已被禁用, 请联系www.derkiot.com");
            }
            else if (cloudReturnByte[0] == 0x08) {
            	DerkUI.logViewln("该账号已被禁用, 请联系www.derkiot.com");
            }
            else if (cloudReturnByte[0] == 0x09) {
            	DerkUI.logViewln("余额不足, 请联系www.derkiot.com充值");
            }
            else {
            	DerkUI.logViewln("未知错误");
            }
            dkCloudID.Close();
            return;
        }

        if ( (cloudReturnByte.length > 300) && (cloudReturnByte[0] == 0x04) ) {
            byte[] decrypted = new byte[cloudReturnByte.length - 3];
            System.arraycopy(cloudReturnByte, 3, decrypted, 0, decrypted.length);
            IDCardData idCardData = new derk.sam.IDCardData(decrypted);
            if ( idCardData.IDCardNo != null ) {
//                showIDMsg(idCardData);

//                //获取照片
//                initData[0] = (byte)0xA0;
//                if ( dkCloudID != null ) {
//                    dkCloudID.Close();
//                }
//                dkCloudID = new DKCloudID();
//                cloudReturnByte = dkCloudID.dkCloudTcpDataExchange(initData);
//                dkCloudID.Close();
//                if ( (cloudReturnByte == null) || (cloudReturnByte.length < 4)) {
//                    logViewln( "获取图片失败！" );
//                }
//                else {
//                    byte[] imageBytes = Arrays.copyOfRange( cloudReturnByte, 3, cloudReturnByte.length );
//                    idCardData.PhotoBmp = GetNetPicture.getURLimage("http://www.dkcloudid.cn:8090/image/" + StringTool.byteHexToSting(imageBytes) + ".bmp");
//                }

                System.out.println("解析成功：" + err_cnt + idCardData.toString());
				DerkUI.logViewln(idCardData.toString());
				DerkUI.showIDMsg(idCardData);
                err_cnt = 0;
            }
            else {
            	DerkUI.logViewln( "数据错误！" );
                System.out.println("数据错误！");
                dkCloudID.Close();

                if (err_cnt++ < NUMBER_OF_REPARSING) {
                	DerkUI.logViewln( "正在重新解析.." );
                    try {
						serialManager.sendMessage(StringTool.hexStringToBytes("AA0118"));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                }
                else {
                    err_cnt = 0;
                }

                return;
            }
        }
        else if ( (cloudReturnByte != null) && (cloudReturnByte.length < 300) && (cloudReturnByte[0] == 0x03) ) {
            //将数据发送给NFC模块
            byte[] bytes = new byte[cloudReturnByte.length + 5];
            int cmdLen = cloudReturnByte.length + 1;
            bytes[0] = SAM_V_FRAME_START_CODE;
            bytes[1] = (byte)((cmdLen & 0xff00) >> 8);
            bytes[2] = (byte)(cmdLen & 0x00ff);
            bytes[3] = SAM_V_APDU_COM;
            System.arraycopy(cloudReturnByte, 0, bytes, 4, cloudReturnByte.length);
            bytes[bytes.length - 1] = UtilTool.bcc_check( bytes );
            final byte[] sendApduBytes = bytes;
            try {
				serialManager.sendMessage(sendApduBytes);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
    }
}

